package com.wmz.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wmz.constant.BusinessEnum;
import com.wmz.constant.HttpConstants;
import com.wmz.constant.ResourceConstants;
import com.wmz.filter.TokenTranslationFilter;
import com.wmz.model.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.PrintWriter;

/**
 * @author wmz
 * @date 2024/7/6 11:15
 * @description 资源服务配置类
 */
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private TokenTranslationFilter tokenTranslationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭跨站，跨域，session
        http.csrf().disable();
        http.cors().disable();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        //使用token过滤器，解析用户信息，放在认证过滤器之前
        http.addFilterBefore(tokenTranslationFilter, UsernamePasswordAuthenticationFilter.class);
        // 配置处理携带token但权限不足的情况
        http.exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint()) // 没有token
                .accessDeniedHandler(accessDeniedHandler());      // 权限不足

        // 配置其他请求
        http.authorizeHttpRequests()
                .antMatchers(ResourceConstants.RESOURCE_ALLOW_URLS) // 放行路径ResourceConstants.RESOURCE_ALLOW_URLS
                .permitAll()
                .anyRequest().authenticated();  // 其他路径都需要认证
    }

    /**
     * 处理没有携带token的请求
     * @return
     */
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return (request, response, authException) -> {
            // 设置响应头
            response.setContentType(HttpConstants.APPLICATION_JSON);
            response.setCharacterEncoding(HttpConstants.UTF_8);
            // 返回结果对象
            Result<String> result = Result.fail(BusinessEnum.UN_AUTHORIZAION);
            ObjectMapper objectMapper = new ObjectMapper();
            String s = objectMapper.writeValueAsString(result);
            PrintWriter writer = response.getWriter();
            writer.write(s);
            writer.flush();
            writer.close();

        };
    }

    /**
     * 处理权限不足的请求
     * @return
     */
    public AccessDeniedHandler accessDeniedHandler() {
        return (request, response, accessDeniedException) -> {
            // 设置响应头
            response.setContentType(HttpConstants.APPLICATION_JSON);
            response.setCharacterEncoding(HttpConstants.UTF_8);
            //返回结果对象
            Result<Object> result = Result.fail(BusinessEnum.ACCESS_DENY_FAIL);
            ObjectMapper objectMapper = new ObjectMapper();
            String s = objectMapper.writeValueAsString(result);
            PrintWriter writer = response.getWriter();
            writer.write(s);
            writer.flush();
            writer.close();
        };
    }

}
